﻿namespace AppLibrary
{
    using System;
    using System.Reflection;
    using System.ServiceModel.Syndication;
    using System.ServiceModel.Web;

    public static class AtomPubUrlProvider
    {
        private const String GetEntryMethodName = "GetEntry";
        private const String GetEntryContentMethodName = "GetEntryContent";

        private static UriTemplate entryUriTemplate;
        private static UriTemplate contentUriTemplate;

        private static UriTemplate EntryUriTemplate
        {
            get
            {
                if (AtomPubUrlProvider.entryUriTemplate == null)
                {
                    MethodInfo getEntryMethod = typeof(IAtomPub).GetMethod(AtomPubUrlProvider.GetEntryMethodName);
                    String templateString = ((WebGetAttribute)Attribute.GetCustomAttribute(getEntryMethod, typeof(WebGetAttribute))).UriTemplate;
                    AtomPubUrlProvider.entryUriTemplate = new UriTemplate(templateString);
                }

                return AtomPubUrlProvider.entryUriTemplate;
            }
        }

        private static UriTemplate ContentUriTemplate
        {
            get
            {
                if (AtomPubUrlProvider.contentUriTemplate == null)
                {
                    MethodInfo getEntryContentMethod = typeof(IAtomPub).GetMethod(AtomPubUrlProvider.GetEntryContentMethodName);
                    String templateString = ((WebGetAttribute)Attribute.GetCustomAttribute(getEntryContentMethod, typeof(WebGetAttribute))).UriTemplate;
                    AtomPubUrlProvider.contentUriTemplate = new UriTemplate(templateString);
                }

                return AtomPubUrlProvider.contentUriTemplate;
            }
        }

        public static Uri GetItemUri(Uri baseUri, String resource, SyndicationItem item)
        {
            return AtomPubUrlProvider.EntryUriTemplate.BindByPosition(baseUri, resource, item.Id);
        }

        public static Uri GetContentUri(Uri baseUri, String resource, SyndicationItem item)
        {
            return AtomPubUrlProvider.ContentUriTemplate.BindByPosition(baseUri, resource, item.Id);
        }

        public static Boolean TryParseItemUri(Uri baseUri, Uri address, ref String resource, ref String entryId)
        {
            try
            {
                UriTemplateMatch match = AtomPubUrlProvider.EntryUriTemplate.Match(baseUri, address);

                resource = match.BoundVariables["resource"];
                entryId = match.BoundVariables["entryId"];

                return true;
            }
            catch (UriTemplateMatchException)
            {
                return false;
            }
        }

        public static Boolean TryParseContentUri(Uri baseUri, Uri address, ref String resource, ref String entryId)
        {
            try
            {
                UriTemplateMatch match = AtomPubUrlProvider.ContentUriTemplate.Match(baseUri, address);

                resource = match.BoundVariables["resource"];
                entryId = match.BoundVariables["entryId"];

                return true;
            }
            catch (UriTemplateMatchException)
            {
                return false;
            }
        }
    }
}
